package com.wy.w_ui.banner.adapter;

import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;

import com.wy.w_ui.banner.core.IWBanner;
import com.wy.w_ui.banner.core.WBannerBean;

import java.util.List;


/**
 * WBanner 适配器,为页面填充数据
 */
public class WBannerAdapter extends PagerAdapter {

    private Context context;
    private SparseArray<WBannerViewHolder> cacheViews = new SparseArray<>();
    private IWBanner.OnBannerClickListener bannerClickListener;
    private IWBindAdapter bindAdapter;
    private List<? extends WBannerBean> models;
    private boolean isAutoPlay = true;
    private boolean loop = false;//非自动轮播状态下是否可以循环切换
    private int layoutResId = -1;

    public WBannerAdapter(Context context) {
        this.context = context;
    }

    /**
     * 设置数据
     * @param models 数据
     */
    public void setModels(List<? extends WBannerBean> models) {
        this.models = models;
        //初始化数据
        initCacheView();
        notifyDataSetChanged();
    }

    /**
     * 设置 adapter
     * @param bindAdapter
     */
    public void setBindAdapter(IWBindAdapter bindAdapter) {
        this.bindAdapter = bindAdapter;
    }

    /**
     * 设置监听事件
     * @param bannerClickListener listener
     */
    public void setBannerClickListener(IWBanner.OnBannerClickListener bannerClickListener) {
        this.bannerClickListener = bannerClickListener;
    }

    /**
     * 设置 item resId
     * @param layoutResId resId
     */
    public void setLayoutResId(int layoutResId) {
        this.layoutResId = layoutResId;
    }

    /**
     * 设置是否自动轮播
     * @param autoPlay autoPlay
     */
    public void setAutoPlay(boolean autoPlay) {
        isAutoPlay = autoPlay;
    }

    /**
     * 设置是否可以非自动轮播状态下是否可以循环切换
     * @param loop loop
     */
    public void setLoop(boolean loop) {
        this.loop = loop;
    }

    /**
     * 获取真实的数量
     */
    public int getRealCount(){
        return models == null ? 0 : models.size();
    }

    /**
     * 通过 viewPager 滚动的 position 获取真实的 position
     */
    public int getRealPosition(int position){
        return position % getRealCount();
    }

    /**
     * 获取初次展示的item的位置
     */
    public int getFirstItem(){
        //总量减去真实数量的余数的值就是真实数量的倍数---就是获取从零开始的位置,太大了除以2取中间
        return Integer.MAX_VALUE / 2 - (Integer.MAX_VALUE / 2) % getRealCount();
    }

    /**
     * 初始化数据
     */
    private void initCacheView(){
        cacheViews = new SparseArray<>();
        for (int i = 0; i < models.size(); i++) {

            if (layoutResId == -1){
                throw new IllegalArgumentException("必须设置一个 layoutResId");
            }

            View rootView =  LayoutInflater.from(context).inflate(layoutResId,null,false);

            WBannerViewHolder viewHolder = new WBannerViewHolder(rootView);

            cacheViews.put(i,viewHolder);
        }
    }


    protected void onBind(@NonNull final WBannerViewHolder viewHolder,@NonNull final WBannerBean bannerMo,final int position){
        viewHolder.rootView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (bannerClickListener != null){
                    bannerClickListener.onBannerClick(viewHolder,bannerMo,position);
                }
            }
        });

        if (bindAdapter != null){
            bindAdapter.onBind(viewHolder,bannerMo,position);
        }
    }


    /**
     * 初始化item
     * @param container
     * @param position
     * @return
     */
    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {

        int realPosition = position;
        if (getRealCount() > 0){
            //0%5=0;1%5=1
            realPosition = position % getRealCount();
        }
        //TODO 为什么这么写
        WBannerViewHolder viewHolder = cacheViews.get(realPosition);
        if (container.equals(viewHolder.rootView.getParent())){
            container.removeView(viewHolder.rootView);
        }

        //数据绑定
        onBind(viewHolder,models.get(realPosition),realPosition);

        if (viewHolder.rootView.getParent() != null){
            ((ViewGroup)viewHolder.rootView.getParent()).removeView(viewHolder.rootView);
        }

        container.addView(viewHolder.rootView);
        return viewHolder.rootView;
    }

    /**
     * 防止 cacheViews 数据被销毁
     * @param container
     * @param position
     * @param object
     */
    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
//        super.destroyItem(container, position, object);
    }

    /**
     * 让 item 每次都会刷新
     * @param object
     * @return
     */
    @Override
    public int getItemPosition(@NonNull Object object) {
        return POSITION_NONE;
    }

    @Override
    public int getCount() {
        //设置无限轮播
        return isAutoPlay ? Integer.MAX_VALUE : (loop ? Integer.MAX_VALUE : getRealCount());
    }

    /**
     * ViewPager里面对每个页面的管理是key-value形式的，也就是说每个page都有个对应的id（id是object类型），需要对page操作的时候都是通过id来完成的
     *
     * 首先看这个函数
     * public Object instantiateItem(ViewGroup container, int position)；
     * 这是pageAdapter里的函数，功能就是往PageView里添加自己需要的page。同时注意它还有个返回值object，这就是那个id。
     *
     * 最后
     * public abstract boolean isViewFromObject (View view, Object object)
     * 这个函数就是用来告诉框架，这个view的id是不是这个object。
     * 谷歌官方推荐把view当id用，所以常规的instantiateItem（）函数的返回值是你自己定义的view，而isViewFromObject（）的返回值是view == object。
     *
     * ps：感觉这个机制应该是历史遗留问题，属于改bug改出来的机制。否则官方不会推荐这种把view当id的做法。
     */
    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }


    /**
     * ViewHolder
     */
    public static class WBannerViewHolder {
        View rootView;
        private SparseArray<View> viewSparseArray;
        public WBannerViewHolder(View rootView) {
            this.rootView = rootView;
        }

        public View getRootView() {
            return rootView;
        }

        public <V extends View> V findViewById(int id){
            if (!(rootView instanceof ViewGroup)){
                return (V) rootView;
            }

            if (this.viewSparseArray == null){
                this.viewSparseArray = new SparseArray<>(1);
            }

            V childView = (V) viewSparseArray.get(id);
            if (childView == null){
                childView = rootView.findViewById(id);
                this.viewSparseArray.put(id,childView);
            }

            return childView;
        }
    }
}
